/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       function_handler.h

	$Header: /game/function_handler.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef FUNCTION_HANDLER_H_INCLUDED
#define FUNCTION_HANDLER_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "handler.h"
// --------------------------------------------------------------------------
// generic callback functions.
//
// typical usage:
//
// void click_1( t_button* );
// 
//     button->set_handler( function_handler( click_1 ) );
//


// ---------------------------------------------------------
// callback which takes a function object / function pointer
// ----------------------------------------------------------
template <class t_function>
class t_function_handler : public t_handler_base
{
public:
	t_function_handler( t_function function ) : m_function( function )
	{
	}

	virtual void operator()()
	{
		m_function();
	}
protected:
	t_function m_function;
};

// ---------------------------------------------------------
// callback which takes a function object / function pointer with 1 parameter
// ----------------------------------------------------------
template <class t_function, class type>
class t_function_handler_1 : public t_handler_base_1<type>
{
public:
	t_function_handler_1( t_function function ) : m_function( function )
	{
	}

	virtual void operator()( type arg )
	{
		m_function(arg);
	}
protected:
	t_function m_function;
};


// ---------------------------------------------------------
// callback which takes a function object / function pointer
// ----------------------------------------------------------
template <class t_function, class type_1, class type_2>
class t_function_handler_2 : public t_handler_base_2<type_1, type_2>
{
public:
	t_function_handler_2( t_function function ) : m_function( function )
	{
	}

	virtual void operator()( type_1 arg_1, type_2 arg_2 )
	{
		m_function(arg_1, arg_2);
	}
protected:
	t_function m_function;
};


// ---------------------------------------------------------
// callback which takes a function object / function pointer
// ----------------------------------------------------------
template <class t_function, class type_1, class type_2, class type_3>
class t_function_handler_3 : public t_handler_base_3<type_1, type_2, type_3>
{
public:
	t_function_handler_3( t_function function ) : m_function( function )
	{
	}

	virtual void operator()( type_1 arg_1, type_2 arg_2, type_3 arg_3 )
	{
		m_function(arg_1, arg_2, arg_3);
	}
protected:
	t_function m_function;
};

// ----------------------------------------------------------------
// helper functions: function_handler( function )
// these adapt any 0, 1, 2, or 3 parameter function to a callback handler.
// They also adapt function objects which take 0 parameters.
// Function objects with 1+ parameters must be constructed manually from
// the appropriate t_function_handler object.
// ------------------------------------------------------------------

// helper function for creating handlers which are pointers to functions
inline t_handler function_handler( void (*function)(void) )
{
	return new t_function_handler< void (*)(void)>( function );
}

// helper function for creating handlers from function objects.
template <class t_function>
inline t_handler function_handler( t_function function )
{
	return new t_function_handler<function>( function );
}

// helper function for creating handlers which are pointers to functions with 1 parameter
template < class type >
inline t_handler_1<type> function_1_handler( void (*function)(type) )
{
	return new t_function_handler_1<void (*)(type), type>( function );
}

// helper function for creating handlers which are pointers to functions with 2 parameters
template < class type_1, class type_2 >
inline t_handler_2<type_1, type_2> function_2_handler( void (*function)(type_1, type_2) )
{
	return new t_function_handler_2<void (*)(type_1, type_2), type_1, type_2>( function );
}


// helper function for creating handlers which are pointers to functions with 3 parameters
template < class type_1, class type_2, class type_3 >
inline t_handler_3<type_1, type_2, type_3>
	   function_3_handler( void (*function)(type_1, type_2, type_3) )
{
	return new t_function_handler_3<void (*)(type_1, type_2, type_3),
		                            type_1, type_2, type_3>( function );
}


#endif // FUNCTION_HANDLER_H_INCLUDED



